package com.frank.test;

import com.alibaba.fastjson.JSON;
import com.frank.utils.UrlSafeBase64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;

public final class Auth {
    public final String accessKey;
    private final SecretKeySpec secretKey;

    private Auth(String accessKey, SecretKeySpec secretKeySpec) {
        this.accessKey = accessKey;
        this.secretKey = secretKeySpec;
    }

    public static Auth create(String accessKey, String secretKey) {
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
        return new Auth(accessKey, secretKeySpec);
    }


    private Mac createMac() {
        try {
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(this.secretKey);
            return mac;
        } catch (GeneralSecurityException var3) {
            var3.printStackTrace();
            throw new IllegalArgumentException(var3);
        }
    }

    public String sign(byte[] data) {
        Mac mac = this.createMac();
        String encodedSign = UrlSafeBase64.encodeToString(mac.doFinal(data));
        return this.accessKey + ":" + encodedSign;
    }

    public String sign(String data) {
        return this.sign(data.getBytes());
    }

    public String signWithData(byte[] data) {
        String s = UrlSafeBase64.encodeToString(data);
        return this.sign(s) + ":" + s;
    }

    public String signWithData(String data) {
        return this.signWithData(data.getBytes());
    }


    public String uploadToken(String bucket) {
        return this.uploadToken(bucket, null, 3600L);
    }

    public String uploadToken(String bucket, String key, long expires) {
        long deadline = System.currentTimeMillis() / 1000L + expires;
        return this.uploadTokenWithDeadline(bucket, key, deadline);
    }

    public String uploadTokenWithDeadline(String bucket, String key, long deadline) {
        String scope = bucket;
        if (key != null) {
            scope = bucket + ":" + key;
        }

        Map x = new HashMap();
        x.put("scope", scope);
        x.put("deadline", Long.valueOf(deadline));
        String s = JSON.toJSONString(x);
        return this.signWithData(s);
    }

}
